package com.dwin.h5.app.ui.fragments;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.AnimationDrawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.dwin.h5.app.H5Application;
import com.dwin.h5.app.R;
import com.dwin.h5.app.models.ResponseBean;
import com.dwin.h5.app.models.UserBean;
import com.dwin.h5.app.models.WeatherModel;
import com.dwin.h5.app.services.mqtt.DataSynEvent;
import com.dwin.h5.app.services.mqtt.MqttManager;
import com.dwin.h5.app.services.mqtt.MqttManagerV2;
import com.dwin.h5.app.services.mqtt.MqttMessageWithTopic;
import com.dwin.h5.app.ui.MainActivityV2;
import com.dwin.h5.app.ui.pages.ConfigureNetAirKissActivity;
import com.dwin.h5.app.ui.pages.ScannerActivityV2;
import com.dwin.h5.app.ui.system.LoginActivity;
import com.dwin.h5.app.utils.AppUtils;
import com.dwin.h5.app.utils.Constants;
import com.dwin.h5.app.utils.DisplayUtil;
import com.dwin.h5.app.utils.ImageHexTool;
import com.dwin.h5.app.utils.MobileUtil;
import com.dwin.h5.app.utils.ToastUtil;
import com.dwin.h5.app.utils.http.OkHttpUtils;
import com.dwin.h5.app.utils.http.WeatherRetrofit;
import com.dwin.h5.app.views.dialogs.NetLoadingDialog;
import com.example.qrcode.Constant;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;

import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.json.JSONArray;
import org.json.JSONObject;
import org.litepal.LitePal;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * H5显示的基类，处理h5的交互逻辑
 * 根据不同的url显示不同页面内容
 */
public class BaseH5FragmentV2 extends BaseFragment {
    private static final String TAG = "BaseH5FragmentV2";
    private static final int CODE_QRCODE = 999;
    public static final int CODE_CONFIG_NET = 1000;

    private String pageUrl; // h5页面的url地址
    private WebView mWebView;

    protected String auth = "";
    protected String qrCodeIdFlag;
    private RelativeLayout rl_loading; // webView 加载中，显示UI
    private RelativeLayout rl_loading_failed; // 加载失败，显示的view
    private boolean h5HasError = false; // h5页面异常，标识位

    //--------------------
    private static final int CODE_LOST = 100; // 网络丢失的code
    private boolean isNetLostFlag = false; // 网络切换，导致mqtt网络连接丢失。
    private boolean isPageVisible = true; // 页面是否可见
    private int cacheMode; // 1:vue模式（使用缓存），0：默认模式，不使用缓存。


    // jsBridge，不能执行UI操作。需要在主线程执行
    private static final int SET_CACHE_MODE = 123;
    private static boolean isSetCached = false;
    Handler mUIHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case SET_CACHE_MODE:
                    android.webkit.WebSettings webSettings = mWebView.getSettings();
                    int mode = msg.arg1;
                    if (mode == 1 && isSetCached == false) {
                        if (!isNetworkConnected(mContext)) { // 无网络
                            webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
                        } else { // 网络正常
                            webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
                        }
                        // mWebView.reload(); // 刷新
                        isSetCached = true;
                    } else {
                        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
                    }
                    break;
                default:
                    break;
            }
        }
    };

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mContext = getActivity();
        return inflater.inflate(R.layout.fragment_base_h5_v2, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        EventBus.getDefault().register(this);
        locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);

        rl_loading = view.findViewById(R.id.rl_loading);
        rl_loading_failed = view.findViewById(R.id.rl_loading_failed);
        ImageView iv_loading = view.findViewById(R.id.iv_loading); // 加载中：页面动画添加
        iv_loading.setBackgroundResource(R.drawable.anim_loading_h5);
        AnimationDrawable ad = (AnimationDrawable) iv_loading.getBackground();
        ad.start();

        mWebView = view.findViewById(R.id.web_view);
        initWebView(mWebView);

        List<UserBean> list = LitePal.findAll(UserBean.class);
        if (list != null && list.size() > 0) {
            mUser = list.get(0); // 获取用户信息
            auth = mUser.auth;
        }

        if (pageUrl != null) {
            mWebView.loadUrl(pageUrl);
            rl_loading.setVisibility(View.VISIBLE);
            Log.d(TAG, "page  is : " + pageUrl);
            Log.d(TAG, "page progress is :0 ");
            mWebView.setWebViewClient(new WebViewClient() {
                @Override
                public void onReceivedError(WebView webView, int i, String s, String s1) {
                    super.onReceivedError(webView, i, s, s1);
                    rl_loading_failed.setVisibility(View.VISIBLE);
                    mWebView.setVisibility(View.INVISIBLE);
                    h5HasError = true;
                    Log.d(TAG, "onReceivedError 0000");
                }

                @Override
                public void onPageFinished(WebView webView, String s) {
                    super.onPageFinished(webView, s);
                    Log.d(TAG, "onPageFinished 0000");
                    rl_loading.setVisibility(View.GONE);
                    if (h5HasError == false) {
                        mWebView.setVisibility(View.VISIBLE);
                        rl_loading_failed.setVisibility(View.GONE);
                        rl_loading.setVisibility(View.GONE);
                    } else {
                        mWebView.setVisibility(View.INVISIBLE);
                    }
                }

                @Override
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    Log.d(TAG, "onPageStarted: " + url);
                    super.onPageStarted(view, url, favicon);
                }

                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    Log.e(TAG, "shouldOverrideUrlLoading: " + url);
                    return super.shouldOverrideUrlLoading(view, url);
                }

                @Nullable
                @Override
                public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

                    return super.shouldInterceptRequest(view, url);
                }
            });
            mWebView.setWebChromeClient(new WebChromeClient() {

            });
        }
        rl_loading_failed.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                rl_loading.setVisibility(View.VISIBLE);
                rl_loading_failed.setVisibility(View.GONE);
                h5HasError = false;
                mWebView.reload(); // 刷新
            }
        });

    }

    /**
     * https://blog.csdn.net/a345017062/article/details/8573689
     * LOAD_DEFAULT，根据cache-control决定是否从网络上取数据。
     * LOAD_CACHE_ELSE_NETWORK，只要本地有，无论是否过期，或者no-cache，都使用缓存中的数据。
     * LOAD_CACHE_ONLY: 不使用网络，只读取本地缓存数据
     * LOAD_NO_CACHE: 不使用缓存，只从网络获取数据.
     */
    private void initWebView(WebView mWebView) {
        android.webkit.WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true); // 允许运行 js 代码
        webSettings.setDomStorageEnabled(true);
        String appCachePath = ((Activity) mContext).getApplication().getCacheDir().getAbsolutePath();
        webSettings.setAppCachePath(appCachePath); // 设置缓存路径
        webSettings.setAppCacheEnabled(true); // 开启Cache存储机制
        webSettings.setUseWideViewPort(true);
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setSupportZoom(false); // 不可缩放
        webSettings.setBuiltInZoomControls(false);
        webSettings.setDisplayZoomControls(true);
        webSettings.setTextZoom(100); // 手机字体设置大小，影响h5页面展示。
        // webSettings.setAppCacheMaxSize(20 * 1024 * 1024);
//        设置缓存策略 LOAD_NO_CACHE LOAD_CACHE_ELSE_NETWORK
//        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); // 默认
//        setCacheMode(mWebView);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); // 修复https图片不显示问题
        }
        MyJaveScriptInterface javeScriptInterface = new MyJaveScriptInterface(mContext); //设置 jsBridge
        mWebView.addJavascriptInterface(javeScriptInterface, "androidJSBridge");
    }

    private void setCacheMode(WebView mWebView) {
        // 总结：根据以上两种模式，建议缓存策略为，判断是否有网络，有的话，使用LOAD_DEFAULT，无网络时，使用LOAD_CACHE_ELSE_NETWORK。
        android.webkit.WebSettings webSettings = mWebView.getSettings();
        if (!isNetworkConnected(mContext)) { // 无网络
            webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        } else { // 网络正常
            webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        }
    }

    private void updateCacheMode(int mode) {
        Message msg = mUIHandler.obtainMessage();
        msg.what = SET_CACHE_MODE;
        msg.arg1 = mode;
        mUIHandler.sendMessage(msg);
    }

    private boolean isMqttMultipleDevices = false; // 是否是多个mqtt设备连接。

    /**
     * h5调用native事件封装
     */
    public class MyJaveScriptInterface {
        private static final String TAG = "MyJaveScriptInterface";
        private Context mContext;

        public MyJaveScriptInterface(Context context) {
            this.mContext = context;
        }

        @JavascriptInterface
        public void H5CallApp(String msg) {
            Log.d(TAG, msg);
            if (msg == null) {
                return;
            }
            if (false == isPageVisible) {
                return; // 页面不可见，不执行js代码
            }
            try {
                JSONObject jsonObject = new JSONObject(msg);
                String type = jsonObject.getString("type");
                String command = jsonObject.getString("command");
                String idflag = jsonObject.getString("idflag");
                String isShowLoading = "1"; // 0不显示转圈圈，1显示转圈圈
                if (jsonObject.has("isShowLoading")) {
                    isShowLoading = jsonObject.getString("isShowLoading");
                }

                if ("4".equals(type)) { // 网络类（http,https,mqtt）
                    if ("http".equals(command) || "https".equals(command)) {
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        String url = jsonData.getString("url");
                        String method = jsonData.getString("method");
                        JSONObject headers = jsonData.getJSONObject("param");
                        Iterator<String> headerkeys = headers.keys();
                        if ("get".equalsIgnoreCase(method)) {
                            Map<String, String> map = new HashMap<>();
                            while (headerkeys.hasNext()) {
                                String key = headerkeys.next();
                                map.put(key, headers.getString(key));
                            }
                            getHttp(url, idflag, isShowLoading, map); // http get 请求
                        } else if ("post".equalsIgnoreCase(method)) {
                            Map<String, Object> map = new HashMap<>();
                            JSONObject jsonParam = new JSONObject(jsonData.getString("param"));
                            Iterator<String> paramKeys = headers.keys();
                            while (paramKeys.hasNext()) {
                                String key = paramKeys.next();
                                Object value = jsonParam.get(key);
                                if (value instanceof String) {
                                    map.put(key, value);
                                } else if (value instanceof JSONArray) { // 针对批量删除数据，处理
                                    JSONArray array = (JSONArray) value;
                                    List<String> ids = new ArrayList<>();
                                    for (int i = 0; i < array.length(); i++) {
                                        ids.add(array.getString(i));
                                    }
                                    map.put(key, ids);
                                } else {
                                    map.put(key, jsonParam.get(key));
                                }
                            }
                            String obj = new Gson().toJson(map);
                            RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), obj);
                            postHttp(url, idflag, isShowLoading, body);
                        }
                    }  // end of http/https
                    else if ("mqtt".equals(command)) {
                        // build message and send to h5 by appCallH5 interface
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        String info = jsonData.getString("info");

                        buildRAMReadMsg(info); // 发送mqtt消息
                    } // end of mqtt
                    else if ("mqttInfo2App".equals(command)) { // 得到mqtt的详细消息
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        JSONObject deviceDetail = jsonData.getJSONObject("deviceDetail"); // 单个设备，为对象的形式
                        String userTopic = deviceDetail.getString("user_topic");
                        String userSendTopic = deviceDetail.getString("user_send_topic");

                        JSONObject mqtt_info = deviceDetail.getJSONObject("mqtt_info");
                        String wxmqttserver = mqtt_info.getString("mqtt_server");
                        String wxmqttport = mqtt_info.getString("mqtt_port");
                        String mqttuser = mqtt_info.getString("mqtt_user");
                        String mqttpw = mqtt_info.getString("mqtt_pw");
                        buildMqttConnect(wxmqttserver, wxmqttport, mqttuser, mqttpw, userTopic, userSendTopic);
                        isMqttMultipleDevices = false;
                    }  // end of mqttInfo2App
                    else if ("mqttMultiDevices".equals(command)) { // 多设备发送mqtt消息
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        String info = jsonData.getString("info");
                        String topic = jsonData.getString("topic");
                        buildRAMReadMsgMultiple(topic, info); // 发送mqtt消息
                    } else if ("mqttInfo2AppMultiDevices".equals(command)) {  // 多设备建立mqtt连接。
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        JSONArray deviceDetail = jsonData.getJSONArray("deviceDetail"); // 多个设备，是数组的形式。
                        if (deviceDetail.length() > 0) {
                            isMqttMultipleDevices = true;
                            JSONObject device = (JSONObject) deviceDetail.get(0); // 获取第一个设备。
                            JSONObject mqtt_info = device.getJSONObject("mqtt_info");
                            String wxmqttserver = mqtt_info.getString("mqtt_server");
                            String wxmqttport = mqtt_info.getString("mqtt_port");
                            String mqttuser = mqtt_info.getString("mqtt_user");
                            String mqttpw = mqtt_info.getString("mqtt_pw");

                            List<String> topicReceivers = new ArrayList<String>(); // 组织订阅主题
                            for (int i = 0; i < deviceDetail.length(); i++) {
                                JSONObject dev = (JSONObject) deviceDetail.get(i);
                                String userSendTopic = dev.getString("user_send_topic"); // user_topic / user_send_topic
                                topicReceivers.add(userSendTopic);
                            }
                            buildMqttConnectV2(wxmqttserver, wxmqttport, mqttuser, mqttpw, topicReceivers);
                        }
//                        String userTopic = deviceDetail.getString("user_topic");
//                        JSONObject mqtt_info = deviceDetail.getJSONObject("mqtt_info");
//                        String wxmqttserver = mqtt_info.getString("mqtt_server");
//                        String wxmqttport = mqtt_info.getString("mqtt_port");
//                        String mqttuser = mqtt_info.getString("mqtt_user");
//                        String mqttpw = mqtt_info.getString("mqtt_pw");
//                        buildMqttConnect(wxmqttserver, wxmqttport, mqttuser,
//                                mqttpw, userTopic, userSendTopic);
                    } // end mqttInfo2AppMultiDevices
                } else if ("3".equals(type)) { // 音频类

                } else if ("2".equals(type)) { // 硬件类
                    qrCodeIdFlag = idflag;
                    if ("setCacheMode".equals(command)) { // 设置缓存模式
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        cacheMode = jsonData.getInt("setCacheMode");
                        updateCacheMode(cacheMode); // TODO
                    } else if ("gps".equals(command)) { // 获取位置信息
                        getAddrInfos();
                    } else if ("qrcode".equals(command)) {
                        callCamera();
                    } else if ("wifi".equals(command)) {
                        callConfigNet();
                    } else if ("setSaveData".equals(command)) { // 保存h5的数据
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        Iterator<String> it = jsonData.keys();
                        while (it.hasNext()) {
                            String key = it.next();
                            String value = jsonData.getString(key);
                            // Log.d(TAG, "save data key: " + key + ", value:" + value);
                            logMessage.edit().putString(key, value).commit();

                            // TODO language重新设定，重新启动app
                            if("language".equals(key) && !TextUtils.isEmpty(value)){
                                Log.d(TAG,  "Language save data key: " + key + ", value:" + value);
                                reStart(mContext);
                            }
                        }
                    } else if ("getSaveData".equals(command)) { // 读取保存的数据，返回给h5
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        Iterator<String> it = jsonData.keys();
                        ResponseBean responseBean = new ResponseBean();
                        responseBean.code = 0;
                        responseBean.message = "获取保存数据成功";
                        Map map = new HashMap();
                        while (it.hasNext()) {
                            String key = it.next();
                            String value = jsonData.getString(key); // 默认为空
                            value = logMessage.getString(key, null); // get log data
                            map.put(key, StringEscapeUtils.escapeJson(value));
                        }
                        // 发送返回的数据给h5
                        responseBean.data = map;
                        appCallH5(mWebView, "", ACTION_HTTP, idflag, responseBean);
                    }
                    // TODO 2021年3月。选择相册图片，选择后，调用http接口保存到php后台。
                    else if ("ringUp".equals(command)) {
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        String phone = jsonData.getString("phone");
                        callPhone(phone); // 拨打电话
                    } else if ("imageFromAlbum".equals(command)) { // 从相册选图
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        imageUrl = jsonData.getString("url");
                        selectImage(0, idflag);
                    } else if ("imageFromCamera".equals(command)) { // 拍照获得图片。
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        imageUrl = jsonData.getString("url");
                        selectImage(1, idflag);
                    }
                } else if ("1".equals(type)) { // 窗口类(隐藏tab)
                    if ("isShowMenu".equals(idflag)) { // 隐藏或显示，底部的Tab栏
                        ((MainActivityV2) getActivity()).setTabsVisiable(command);
                        if ("show".equals(command)) { // 断开mqtt连接
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    if (isMqttMultipleDevices) {
                                        MqttManagerV2.getInstance().release();
                                    } else {
                                        MqttManager.getInstance().release();
                                    }
                                    if (mqttHandler != null) {
                                        mqttHandler.removeMessages(CODE_LOST);
                                    }
                                }
                            }).start();
                        }
                    }
                    // 选择了退出功能
                    if ("logout".equals(idflag) && "logout".equals(command)) {
                        // 退出逻辑，删除用户数据，回到登录页面
                        LitePal.deleteAll(UserBean.class); // 先删除所有用户数据
                        Intent intent = new Intent(mContext, LoginActivity.class);
                        intent.setFlags(intent.FLAG_ACTIVITY_CLEAR_TASK | intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                    }
                    // 主页面Tab切换动作  {"type":"1","command":"tab2","idflag":"switchHomeTab","data":{}}
                    if ("switchHomeTab".equals(idflag)) {
                        ((MainActivityV2) getActivity()).selectTab(command);
                    }
                    if ("jd".equals(idflag) && "jd".equals(command)) {
                        JSONObject jsonData = jsonObject.getJSONObject("data");
                        if (jsonData.has("shopId")) {
                            String shopId = jsonData.getString("shopId");
                            jumpToJDApp(shopId, null);
                        } else {
                            if (jsonData.has("goodId")) {
                                String goodId = jsonData.getString("goodId");
                                jumpToJDApp(null, goodId);
                            } else { // 跳转到京东首页
                                jumpToJDApp(null, null);
                            }
                        }
                    } // end jd

                } else { // 默认值0或为空

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void callPhone(String phone) {
        mPhone = phone;
        if (hasPermission(Manifest.permission.CALL_PHONE)) {
            doCallPhonePermission();
        } else {
            requestPermissions(Constants.CALL_PHONE, Manifest.permission.CALL_PHONE);
        }
    }

    private String mPhone; // 电话临时保存
    @Override
    public void doCallPhonePermission() {
        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri data = Uri.parse("tel:" + mPhone);
        intent.setData(data);
        startActivity(intent);
    }

    /**
     * 既没有商家id，也没有商品id，跳转到首页。
     * 有商家id，跳转到商家详情；无商家id，有商品id，跳转到商品详情。
     *
     * @param shopId
     * @param goodId
     */
    private void jumpToJDApp(String shopId, String goodId) {
        String jdAppId = "com.jingdong.app.mall";
        if (shopId == null && goodId == null) {
            if (AppUtils.checkPackage(getActivity(), jdAppId)) { // 打开京东app主页面
                startActivity(mContext.getPackageManager().getLaunchIntentForPackage("com.jingdong.app.mall"));
            }
            return;
        }
        if (shopId != null) { // 商家详情页面
            if (AppUtils.checkPackage(getActivity(), jdAppId)) {
                String jdAppStr_shop = "openApp.jdMobile://virtual?params={\"category\":\"jump\",\"des\":\"jshopMain\",\"shopId\":\"" + shopId + "\",\"sourceType\":\"M_sourceFrom\",\"sourceValue\":\"dp\"}";
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(jdAppStr_shop));
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
            }
        } else if (goodId != null) { // 商品详情页面
            if (AppUtils.checkPackage(getActivity(), jdAppId)) {
                String url = "openapp.jdmobile://virtual?params=%7B%22sourceValue%22:%220_productDetail_97%22,%22des%22:%22productDetail%22,%22skuId%22:%22" + goodId + "%22,%22category%22:%22jump%22,%22sourceType%22:%22PCUBE_CHANNEL%22%7D";
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(intent);
            }
        }
    }


    // 重新加载WebView
    public void reLoadPage() {
        if (pageUrl != null) {
            h5HasError = false;
            mWebView.loadUrl(pageUrl);
            rl_loading_failed.setVisibility(View.GONE);
            rl_loading.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mWebView.removeJavascriptInterface("androidJSBridge");
        EventBus.getDefault().unregister(this);
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (isMqttMultipleDevices) {
                    MqttManagerV2.getInstance().release();
                } else {
                    MqttManager.getInstance().release();
                }
                if (mqttHandler != null) {
                    mqttHandler.removeMessages(CODE_LOST);
                }
            }
        }).start();
    }

    public void setPageUrl(String url) {
        this.pageUrl = url.trim();
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "page onResume ok ");
        isPageVisible = true;
    }

    @Override
    public void onPause() {
        super.onPause();
        isPageVisible = false;
    }

    // 使用fragmentManager操作fragment的show和hide(注意：第一次创建fragment不会创建此方法)
    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden) { // 隐藏不可见
            Log.d(TAG, "onHiddenChanged hide " + pageUrl);
            ResponseBean responseBean = new ResponseBean();
            responseBean.code = 0;
            responseBean.message = "当前tab被隐藏：" + pageUrl;
            JsonObject object = new JsonObject();
            responseBean.data = object;
            appCallH5(mWebView, "", "hide", "nativeSwitchTab", responseBean);
        } else { // 显示
            Log.d(TAG, "onHiddenChanged show " + pageUrl);
            ResponseBean responseBean = new ResponseBean();
            responseBean.code = 0;
            responseBean.message = "当前tab显示出来：" + pageUrl;
            JsonObject object = new JsonObject();
            responseBean.data = object;
            appCallH5(mWebView, "", "show", "nativeSwitchTab", responseBean);
        }
    }

    /**
     * 子线程创建mqtt连接, 处理多设备连接问题。
     *
     * @param wxmqttserver
     * @param wxmqttport
     * @param mqttuser
     * @param mqttpw
     * @param topics       待订阅主题列表
     */
    private void buildMqttConnectV2(final String wxmqttserver, final String wxmqttport, final String mqttuser,
                                    final String mqttpw, List<String> topics) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String mqttUrl = "tcp://" + wxmqttserver + ":" + wxmqttport;
                String deviceUniId = MobileUtil.getUniqueId4Mqtt(mContext);
                try {
                    MqttManagerV2.getInstance().disConnect();
                    MqttManagerV2.release();
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                Log.d(TAG, "userSendTopics:" + topics.toString());
                List<String> userSendTopics = new ArrayList<>();
                for (String topic : topics) {
                    userSendTopics.add(replaceLast(topic, "cli", "json"));
//                    userSendTopics.add(replaceLast(topic, "cli", "image"));
                }
                boolean b = MqttManagerV2.getInstance().creatConnect(mqttUrl, mqttuser, mqttpw,
                        listToArray(userSendTopics), deviceUniId);
                if (b) {
                    MqttManagerV2.getInstance().subscribe(); // 订阅消息
                    ResponseBean responseBean = new ResponseBean();
                    responseBean.code = 0;
                    responseBean.message = "获取查询mqtt指令";
                    Map map = new HashMap();
                    responseBean.data = map;
                    appCallH5(mWebView, "", ACTION_MQTT, "mqttQuery", responseBean);
                    if (mqttHandler != null) {
                        mqttHandler.removeMessages(CODE_LOST);
                    }
                    Log.d(TAG, "mqtt update UI 建立连接成功：" + b);
                } else {
                    Log.d(TAG, "mqtt update UI 建立连接失败：" + b);
                    isNetLostFlag = true;
                }
            }
        }).start();
    }


    // 子线程创建mqtt连接
    private void buildMqttConnect(final String wxmqttserver, final String wxmqttport, final String mqttuser,
                                  final String mqttpw, final String userTopic, final String userSendTopic) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String mqttUrl = "tcp://" + wxmqttserver + ":" + wxmqttport;
                String deviceUniId = MobileUtil.getUniqueId4Mqtt(mContext);
                try {
                    MqttManager.getInstance().disConnect();
                    MqttManager.release();
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                Log.d(TAG, "userTopic:" + userTopic);
                Log.d(TAG, "userSendTopic:" + userSendTopic);
                List<String> userSendTopics = new ArrayList<>();
                userSendTopics.add(replaceLast(userSendTopic, "cli", "json"));
                userSendTopics.add(replaceLast(userSendTopic, "cli", "image"));

                boolean b = MqttManager.getInstance().creatConnect(mqttUrl, mqttuser, mqttpw,
                        replaceLast(userTopic, "cli", "json"),
                        listToArray(userSendTopics), deviceUniId);
//                boolean b = MqttManager.getInstance().creatConnect(mqttUrl, mqttuser, mqttpw,
//                        replaceLast(userTopic, "cli", "json"),
//                        replaceLast(userSendTopic, "cli", "json"), deviceUniId);
                if (b) {
                    MqttManager.getInstance().subscribe(); // 订阅消息
                    ResponseBean responseBean = new ResponseBean();
                    responseBean.code = 0;
                    responseBean.message = "获取查询mqtt指令";
                    Map map = new HashMap();
                    responseBean.data = map;
                    appCallH5(mWebView, "", ACTION_MQTT, "mqttQuery", responseBean);
                    if (mqttHandler != null) {
                        mqttHandler.removeMessages(CODE_LOST);
                    }
                    Log.d(TAG, "mqtt update UI 建立连接成功：" + b);
                } else {
                    Log.d(TAG, "mqtt update UI 建立连接失败：" + b);
                    isNetLostFlag = true;
                }
            }
        }).start();
    }


    @Subscribe
    public void onEvent(DataSynEvent message) {
        String desc = message.getDetail();
        Log.d(TAG, "1022网络丢失啦------> " + desc);
        // mqtt网络丢失，释放资源，重新建立连接
        isNetLostFlag = true;
        if (mqttHandler != null) {
            mqttHandler.removeMessages(CODE_LOST);
            mqttHandler.sendEmptyMessageDelayed(CODE_LOST, 10 * 1000);
        }
    }

    //  通过EventBus，获取收到的mqtt消息
    @Subscribe
    public void onEvent(MqttMessageWithTopic messageWithTopic) {
        MqttMessage message = messageWithTopic.message;
        String payLoad = new String(message.getPayload());
        Log.d(TAG, "onEvent mqtt Msg: " + payLoad);
        ResponseBean responseBean = new ResponseBean();
        responseBean.code = 0;
        responseBean.message = "收到mqtt";
        responseBean.topic = messageWithTopic.topic; // 设备主题
//        Type type = new TypeToken<JsonObject>() {}.getType();
//        JsonObject object = new Gson().fromJson(payLoad, type);
//        responseBean.data = object;
        responseBean.data = StringEscapeUtils.escapeJson(payLoad);
        appCallH5(mWebView, "", ACTION_MQTT, "getMqttInfo", responseBean);
    }

    @Subscribe
    public void onEvent(String hexMsg) { // 地创三维，组装图片Image
        // 图片的hex数据
        Log.d(TAG, "Image mqtt Msg: " + hexMsg);
        String result = ImageHexTool.handleImageData(hexMsg);
        if (result != null) { // 得到了完整的数据
            result = result.replaceAll("\n", "\\n");

            Log.d(TAG, "Image result: " + result);
            ResponseBean responseBean = new ResponseBean();
            responseBean.code = 0;
            responseBean.message = "获取设备拍照的图片成功";
            Map map = new HashMap();
            map.put("image", result);
            responseBean.data = map;
            appCallH5(mWebView, "", ACTION_MQTT, "showPhoto", responseBean);
        }
    }


    Handler mqttHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            reConnectMqtt(); // MQTT 网络重连
        }
    };

    private void reConnectMqtt() {
        if (isNetLostFlag) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    boolean b = false;
                    if (isMqttMultipleDevices) {
                        b = MqttManagerV2.reConnect();
                    } else {
                        b = MqttManager.reConnect();
                    }
                    if (b) {
                        if (isMqttMultipleDevices) {
                            MqttManagerV2.getInstance().subscribe(); // 订阅消息
                        } else {
                            MqttManager.getInstance().subscribe(); // 订阅消息
                        }
                        if (mqttHandler != null) {
                            mqttHandler.removeMessages(CODE_LOST);
                        }
                        Log.d(TAG, "mqtt reCon 建立连接成功：" + b);
                    } else {
                        if (mqttHandler != null) {
                            mqttHandler.removeMessages(CODE_LOST);
                            mqttHandler.sendEmptyMessageDelayed(CODE_LOST, 10 * 1000);
                        }
                    }
                }
            }).start();
        }
    }

    // 压缩图片，并保存到本地路径中
    private String compressImageAndSave(String imgPath) {
        Bitmap bitmap;
        File picture = new File(imgPath);
        BitmapFactory.Options options = new BitmapFactory.Options();
        //下面这个设置是将图片边界不可调节变为可调节
        options.inJustDecodeBounds = true;
        options.inSampleSize = 2;
        bitmap = BitmapFactory.decodeFile(picture.getAbsolutePath(), options);
        float imagew = 350;
        float imageh = 350;
        int yRatio = (int) Math.ceil(options.outHeight / imageh);
        int xRatio = (int) Math.ceil(options.outWidth / imagew);
        if (yRatio > 1 || xRatio > 1) {
            if (yRatio > xRatio) {
                options.inSampleSize = yRatio;
            } else {
                options.inSampleSize = xRatio;
            }
        }
        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(picture.getAbsolutePath(), options);
        if (bitmap != null) {
            return saveBitmap(bitmap);
        }
        return imgPath;
    }

    public String saveBitmap(Bitmap bitmap) {
        String filePath = Environment.getExternalStorageDirectory() + "/" + PICTURE_FILE;
        File f = new File(filePath);
        if (f.exists()) {
            f.delete();
        }
        try {
            FileOutputStream out = new FileOutputStream(f);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filePath;
    }


    // 上传图片
    protected void postHttpFile(final String url, String pathName) {
        File file = null;
        try {
            String newPath = compressImageAndSave(pathName);
            file = new File(newPath);
            //  图片文件太大，需要处理

        } catch (Exception e) {
            e.printStackTrace();
        }
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        if (file != null) {
            builder.addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image*//*"), file));
        }
        MultipartBody requestBody = builder.build();
        OkHttpUtils.getInstance().postFile(auth, language, url, requestBody, new OkHttpUtils.RealCallback() {
            @Override
            public void onResponse(Call call, Response response) {
                try {
                    String responseData = response.body().string();
                    Type type = new TypeToken<ResponseBean>() {
                    }.getType();
                    ResponseBean bean = new Gson().fromJson(responseData, type);
                    String msg = bean.message;
                    logDebug(TAG + " postHttp result:", responseData);
                    JSONObject jsonObject = new JSONObject(responseData);
                    int code = bean.code;
                    if (response.isSuccessful() && code == Constants.HTTP_OK) {
                        appCallH5(mWebView, "", ACTION_HTTP, imageIdFlag, bean);
                    } else {
                        appCallH5(mWebView, "", ACTION_HTTP, imageIdFlag, bean);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                NetLoadingDialog.dismissprogress();
            }

            @Override
            public void onFailure(Call call, IOException e) {
                NetLoadingDialog.dismissprogress();
            }
        });
    }


    // HTTP Post 请求
    protected void postHttp(final String url, final String idFlag, final String isShowLoading, RequestBody body) {
        if (!isNetworkConnected(mContext)) {
            ToastUtil.toastShort(mContext, R.string.net_error);
            return;
        }
        if ("1".equals(isShowLoading)) {
            NetLoadingDialog.showprogress(mContext, false);
        }
        language = logMessage.getString("language", "zh");
        OkHttpUtils.getInstance().post(auth, language, url, body, new OkHttpUtils.RealCallback() {
            @Override
            public void onResponse(Call call, Response response) {
                try {
                    String responseData = response.body().string();
                    Type type = new TypeToken<ResponseBean>() {
                    }.getType();
                    ResponseBean bean = new Gson().fromJson(responseData, type);
                    String msg = bean.message;
//                    Log.d(TAG, "postHttp result: " + responseData);
                    logDebug(TAG + " postHttp result:", responseData);
                    JSONObject jsonObject = new JSONObject(responseData);
                    int code = bean.code;
                    if (response.isSuccessful() && code == Constants.HTTP_OK) {
                        appCallH5(mWebView, "", ACTION_HTTP, idFlag, bean);
                    } else {
                        appCallH5(mWebView, "", ACTION_HTTP, idFlag, bean);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                NetLoadingDialog.dismissprogress();
            }

            @Override
            public void onFailure(Call call, IOException e) {
                NetLoadingDialog.dismissprogress();
            }
        });
    }

    // get请求
    protected void getHttp(String url, final String idFlag, final String isShowLoading, Map<String, String> map) {
        if (!isNetworkConnected(mContext)) {
            ToastUtil.toastShort(mContext, R.string.net_error);
            return;
        }
        if ("1".equals(isShowLoading)) {
            NetLoadingDialog.showprogress(mContext, false);
        }
        language = logMessage.getString("language", "zh");
        OkHttpUtils.getInstance().get(auth, language, url, map, new OkHttpUtils.RealCallback() {
            @Override
            public void onResponse(Call call, Response response) {
                try {
                    String responseData = response.body().string();
//                    Log.d(TAG, "getHttp result: " + responseData);
                    logDebug(TAG + " getHttp result:", responseData);
                    Type type = new TypeToken<ResponseBean>() {
                    }.getType();
                    final ResponseBean bean = new Gson().fromJson(responseData, type);
                    String msg = bean.message;
                    appCallH5(mWebView, "", ACTION_HTTP, idFlag, bean);
                    if (response.isSuccessful() && bean.code == Constants.HTTP_OK) {
                    } else {
                        ToastUtil.toastShort(mContext, msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                NetLoadingDialog.dismissprogress();
            }

            @Override
            public void onFailure(Call call, IOException e) {
                NetLoadingDialog.dismissprogress();
            }
        });
    }

    /**
     * app 调用h5的共用方法
     *
     * @param webView
     * @param method
     * @param action
     * @param idFlag
     * @param object
     */
    protected void appCallH5(final WebView webView, String method, String action, String idFlag, Object object) {
        this.mWebView = webView;
        final Map<String, Object> map = new HashMap<>();
        if (!TextUtils.isEmpty(action)) {
            map.put("action", action);
        }
        map.put("idflag", idFlag);
        map.put("data", object);
        final String json = new Gson().toJson(map);
        logDebug(TAG + " appCallH5 json:", json);
        //---------------------
        //---------------------
        mWebView.post(new Runnable() {
            @Override
            public void run() {
                webView.evaluateJavascript("javascript:appCallH5('" + json + "')", new ValueCallback<String>() { // TODO ok
                    //                       webView.evaluateJavascript("javascript:appCallH5('999')", new ValueCallback<String>() { //  ok
//                webView.evaluateJavascript("javascript:appCallH5(" +json + ")", new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String s) {
                        Log.d(TAG, "onReceiveValue: " + s);
                    }
                });
            }
        });
    }

    // 已获得地址信息, 请求更新天气信息
    public void getAddrInfos() {
        // 系统定位是否开启
        boolean flagGps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean flagNetLoc = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (flagGps == false && flagNetLoc == false) {
            ResponseBean responseBean = new ResponseBean();
            responseBean.code = -1;
            responseBean.message = "手机系统定位未开启";
            Map map = new HashMap();
            map.put("city", "");
            responseBean.data = map;
            appCallH5(mWebView, "", "", "getCity", responseBean);
            return;
        }
        if (H5Application.addressComponent != null
                && H5Application.addressComponent.city != null
                && getActivity() != null
                && !getActivity().isDestroyed()) {
            String city = H5Application.addressComponent.city;
            if (city != null) { // 获取城市正常
                ResponseBean responseBean = new ResponseBean();
                responseBean.code = 0;
                responseBean.message = "获取城市名称完成";
                Map map = new HashMap();
                map.put("city", H5Application.addressComponent.city);
                map.put("district", H5Application.addressComponent.district);
                map.put("province", H5Application.addressComponent.province);
                map.put("street", H5Application.addressComponent.street);
                map.put("street_number", H5Application.addressComponent.street_number);
                map.put("direction", H5Application.addressComponent.direction);

                map.put("latitude", H5Application.lat);
                map.put("longitude", H5Application.lng);
                responseBean.data = map;
                appCallH5(mWebView, "", "", "getCity", responseBean);
            }
        } else {
            // 未定位成功，请求定位权限并定位
            if (hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)) {
                doCoarseLocation();
            } else {
                requestPermissions(Constants.COARSE_LOCATION_CODE,
                        Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION);
            }
        }
    }

    LocationManager locationManager;
    TestLocationListener locationListener = new TestLocationListener();

    @Override
    public void doCoarseLocation() {
        if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
        }
    }

    // 定位获取经纬度，监听
    private class TestLocationListener implements LocationListener {
        @Override
        public void onLocationChanged(Location location) {
            String msg = "onLocationChanged:latitude-> " + location.getLatitude() + " Longtitude-> " + location.getLongitude();
            Log.d(TAG, "fragment:" + msg);
            // 位置发生改变时，调用这个方法
            getCityInfo(location.getLatitude(), location.getLongitude());
            locationManager.removeUpdates(locationListener);
        }

        @Override
        public void onProviderDisabled(String arg0) {
        }

        @Override
        public void onProviderEnabled(String arg0) {
        }

        @Override
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        }
    }

    // 根据经纬度，调用百度API，获取城市名称等信息， 并反馈给H5页面。
    private void getCityInfo(final double lat, final double Lng) {
        WeatherRetrofit.getInstance().getLocInfo(lat + "," + Lng, new retrofit2.Callback<WeatherModel>() {
            @Override
            public void onResponse(retrofit2.Call<WeatherModel> call, retrofit2.Response<WeatherModel> response) {
                if ("OK".equals(response.body().status)) {
                    // 验证码发送完成
                    H5Application.addressComponent = response.body().result.addressComponent;
                    H5Application.lat = lat;
                    H5Application.lng = Lng;
                    // 将位置信息反馈给h5
                    if (H5Application.addressComponent != null
                            && H5Application.addressComponent.city != null
                            && getActivity() != null
                            && !getActivity().isDestroyed()) {
                        String city = H5Application.addressComponent.city;
                        if (city != null) { // 获取城市正常
                            ResponseBean responseBean = new ResponseBean();
                            responseBean.code = 0;
                            responseBean.message = "获取城市名称完成";
                            Map map = new HashMap();
                            map.put("city", H5Application.addressComponent.city);
                            map.put("district", H5Application.addressComponent.district);
                            map.put("province", H5Application.addressComponent.province);
                            map.put("street", H5Application.addressComponent.street);
                            map.put("street_number", H5Application.addressComponent.street_number);
                            map.put("direction", H5Application.addressComponent.direction);
                            map.put("latitude", lat);
                            map.put("longitude", Lng);
                            responseBean.data = map;
                            appCallH5(mWebView, "", ACTION_HTTP, "getCity", responseBean);
                        }
                    }
                }
            }

            @Override
            public void onFailure(retrofit2.Call<WeatherModel> call, Throwable t) {
                Log.d(TAG, "onFailure: ");
            }
        });
    }


    protected int imageSource = 0; // 图片来源：0相册，1相机
    protected String imageUrl; // 图片上传的url
    protected int actionType = 0; // 0 二维码拍照，1 相册图片
    public String PICTURE_FILE = "test.jpg";
    protected String imageIdFlag = ""; // 图片选择的idflag

    protected void selectImage(int source, String idFlag) {
        imageSource = source;
        imageIdFlag = idFlag;
        actionType = 1;
        if (hasPermission(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            doCameraPermission();
        } else {
            requestPermissions(Constants.CAMERA_CODE, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
    }


    // 配网页面
    protected void callConfigNet() {
        Intent intent = new Intent(mContext, ConfigureNetAirKissActivity.class);
        startActivityForResult(intent, CODE_CONFIG_NET);
    }

    // 调用相机，扫描二维码
    protected void callCamera() {
        if (hasPermission(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            actionType = 0;
            doCameraPermission();
        } else {
            requestPermissions(Constants.CAMERA_CODE, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
    }

    @Override
    public void doCameraPermission() {
        if (actionType == 0) {
            Intent intent = new Intent(mContext, ScannerActivityV2.class);
            // 设置扫码框的宽，高度，位置， 可以从相册获取
            intent.putExtra(Constant.EXTRA_SCANNER_FRAME_WIDTH, DisplayUtil.dip2px(mContext, 257));
            intent.putExtra(Constant.EXTRA_SCANNER_FRAME_HEIGHT, DisplayUtil.dip2px(mContext, 257));
            intent.putExtra(Constant.EXTRA_SCANNER_FRAME_TOP_PADDING, DisplayUtil.dip2px(mContext, 136));
            intent.putExtra(Constant.EXTRA_IS_ENABLE_SCAN_FROM_PIC, true);
            startActivityForResult(intent, CODE_QRCODE);
        } else {
            if (imageSource == 0) { // 相册
                Intent intent = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, 102);
            } else { // 相机
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                File file = new File(Environment.getExternalStorageDirectory(), PICTURE_FILE);
                Uri imageUri = null;
                if (Build.VERSION.SDK_INT >= 24) { // android 7.0以上系统
                    String authority = mContext.getPackageName() + ".fileprovider";
//                    String authority = "com.dwin.h5.fileprovider";
                    imageUri = FileProvider.getUriForFile(mContext, authority, file);
                    List<ResolveInfo> resInfoList = mContext.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
                    for (ResolveInfo resolveInfo : resInfoList) {
                        String packageName = resolveInfo.activityInfo.packageName;
                        mContext.grantUriPermission(packageName, imageUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    }
                } else {
                    imageUri = Uri.fromFile(file);
                }
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(intent, 101);
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 102 && resultCode == Activity.RESULT_OK) { // 相册取照片
            try {
                Uri selectedImage = data.getData(); //获取系统返回的照片的Uri
                String[] filePathColumn = {MediaStore.Images.Media.DATA};
                Cursor cursor = mContext.getContentResolver().query(selectedImage,
                        filePathColumn, null, null, null);//从系统表中查询指定Uri对应的照片
                cursor.moveToFirst();
                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String path = cursor.getString(columnIndex);  //获取照片路径
                cursor.close();
                postHttpFile(imageUrl, path);
            } catch (Exception e) {
                e.printStackTrace();
            }

        } else if (requestCode == 101 && resultCode == Activity.RESULT_OK) { // 相册拍照
            String filePath = Environment.getExternalStorageDirectory() + "/" + PICTURE_FILE; // 图片路径
            File f = new File(filePath);
            if (f == null || f.length() == 0) {
                return;
            }
            postHttpFile(imageUrl, filePath);


        } else if (requestCode == CODE_QRCODE && resultCode == Activity.RESULT_OK) { // 二维码扫描结果
            if (data == null) {
                return;
            }
            String result = data.getExtras().getString(Constant.EXTRA_RESULT_CONTENT);
            // ToastUtil.toastLong(mContext, result); // 扫码成功后，回toast弹框提示。
            ResponseBean responseBean = new ResponseBean();
            responseBean.code = 0;
            responseBean.message = "扫码成功";
            Map map = new HashMap();
            map.put("qrcode", result);
            responseBean.data = map;
            appCallH5(mWebView, "", ACTION_HTTP, qrCodeIdFlag, responseBean);
        } else if (requestCode == CODE_CONFIG_NET && resultCode == Activity.RESULT_OK) {
            // 配网成功了，保存位置信息
            String device_bssid = data.getExtras().getString("device_bssid");
            ResponseBean responseBean = new ResponseBean();
            responseBean.code = 0;
            responseBean.message = "设备配网成功";
            Map map = new HashMap();
            map.put("device_bssid", device_bssid);
            map.put("gps_lat", H5Application.lat);
            map.put("gps_lng", H5Application.lng);
            map.put("gps_nation", H5Application.nation);
            if (H5Application.addressComponent != null) {
                map.put("gps_province", H5Application.addressComponent.province);
                map.put("gps_city", H5Application.addressComponent.city);
                map.put("gps_district", H5Application.addressComponent.district);
                map.put("gps_street", H5Application.addressComponent.street);
                map.put("gps_street_number", H5Application.addressComponent.street_number);
            } else {
                map.put("gps_province", "");
                map.put("gps_city", "");
                map.put("gps_district", "");
                map.put("gps_street", "");
                map.put("gps_street_number", "");
            }
            responseBean.data = map;
            appCallH5(mWebView, "", ACTION_HTTP, "deviceSaveAddress", responseBean);
        }
    }

    private BitmapFactory.Options getBitmapOption(int inSampleSize) {
        System.gc();
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPurgeable = true;
        options.inSampleSize = inSampleSize;
        return options;
    }

    // 单个设备，发送mqtt消息给设备
    private void buildRAMReadMsg(final String message) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "send query hex value: " + message);
                MqttManager.getInstance().publish(message.getBytes());
            }
        }).start();
    }

    // 多个设备，发送mqtt消息给设备
    private void buildRAMReadMsgMultiple(final String topic, final String message) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "send query hex value: " + message);
                MqttManagerV2.getInstance().publish(topic, message.getBytes());
            }
        }).start();
    }

    public boolean webViewGoBack() {
        if (mWebView != null && mWebView.canGoBack()) {
            String url = mWebView.getUrl(); // h5页面，当前的url
//            Log.d(TAG, "webViewGoBack pageUrl--" + pageUrl);
//            Log.d(TAG, "webViewGoBack url--" + url);
            if (pageUrl != null && !pageUrl.equals(url)) {
                mWebView.goBack();
                return true;
            }
        }
        return false;
    }

}
